package presentation.windows;
import java.awt.Font ;
import java.rmi.RemoteException ;
import java.text.SimpleDateFormat ;
import java.util.Calendar ;
import java.util.Date ;
import java.util.Set ;

import javax.swing.ButtonGroup ;
import javax.swing.JButton ;
import javax.swing.JLabel ;
import javax.swing.JList ;
import javax.swing.JOptionPane ;
import javax.swing.JPanel ;
import javax.swing.JRadioButton ;
import javax.swing.JScrollPane ;
import javax.swing.JTextArea ;
import javax.swing.JTextField ;
import javax.swing.ListModel ;
import javax.swing.ListSelectionModel ;
import javax.swing.event.ListSelectionEvent ;
import javax.swing.event.ListSelectionListener ;

import presentation.UIPost ;
import presentation.models.SearchResListCellRenderer ;
import presentation.models.SearchResListModel ;
import util.DateTools ;
import util.Log ;
import util.NotFoundException ;
import util.Subsystem ;

import com.cloudgarden.layout.AnchorConstraint ;
import com.toedter.calendar.JDateChooser ;

import domain.searchEngine.SearchResult ;





/**
 * panel for searching messages, and presenting the results
 */
public class SearchPanel extends BasePanel implements ListSelectionListener
{
	private static final long serialVersionUID = 8396834532748508751L ;
	private JTextField searchContent;
	private JRadioButton byContentRadioButton;
	private JRadioButton byAuthorRadioButton;
	private JRadioButton textRadioButton;
	private JRadioButton byDateRadioButton;
	private JPanel fromDatePane;
	private JScrollPane jScrollPane2;
	private JButton searchButton;
	private JLabel showContentLable;
	private JTextArea postTextArea;
	private JScrollPane jScrollPane1;
	private JList reultsList;
	private JLabel resultsLable;
	private JPanel toDatePane;
	private JLabel toDateLable;
	private JLabel fromDateLable;
	private ButtonGroup textOrDateButtonGroup;
	private ButtonGroup searchByButtonGroup;
	private JLabel searchLabel;
	private JDateChooser fromDate;
	private JDateChooser toDate;

	/**
	 * construct SearchPanel for performing a search in the forum messages
	 * @param sharedData - shared data to all panels, that is created once in the MainFrame
	 */
	public SearchPanel(final SharedUIData sharedData)
	{
		super(sharedData) ;
		this.setPreferredSize(new java.awt.Dimension(735, 550));
		this.initGUI();
		this.makeVisible();
	}

	/**
	 * @see javax.swing.event.ListSelectionListener#valueChanged(javax.swing.event.ListSelectionEvent)
	 */
	@Override
	public void valueChanged(final ListSelectionEvent evt)
	{
		if (evt.getValueIsAdjusting())
		{
			return; //not a valid selection
		}

		if (this.reultsList.getSelectedIndex() != -1) //there was a selection
		{

			SearchResult chosenResult = (SearchResult)this.reultsList.getSelectedValue();
			UIPost resultPost = chosenResult.getPost();

			Log.getLogger(Subsystem.PRESENTATION_MODEL).finest("presnting result with score "+chosenResult.getScore()+" and message: "+resultPost.getMessage());


			this.postTextArea.setText(resultPost.getMessage());
			long authorId = resultPost.getWriterId();
			try
			{
				String authorUserName = this.forum.getMemberById(authorId).getUsername();
				String messageContent = resultPost.getMessage();
				SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy");
				String timeOfPost = df.format(resultPost.getDate());
				this.postTextArea.setText("Author: "+ authorUserName + "\nCreated: " + timeOfPost + "\n" + messageContent);
			}
			catch(NotFoundException e)
			{
				Log.getLogger(Subsystem.PRESENTATION_MODEL).info("writer of post was not found");
				JOptionPane.showMessageDialog(SearchPanel.this,
					"could not find the message author", "error occured", JOptionPane.ERROR_MESSAGE);
			}
			catch(RemoteException e)
			{
				Log.getLogger(Subsystem.PRESENTATION_MODEL).info("Remote problems thrown in search panel, when getting result writer");
				JOptionPane.showMessageDialog(SearchPanel.this,
					"Communication problems, please try again", "error occured", JOptionPane.ERROR_MESSAGE);
			}
		}
	}



	private void initGUI()
	{
		//search button
		this.searchButton = new JButton();
		this.searchButton.setText("Search");
		this.searchButton.setPreferredSize(new java.awt.Dimension(89, 27));
		this.add(this.searchButton, new AnchorConstraint(228, 893, 277, 772, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));

		this.searchButton.addActionListener(new java.awt.event.ActionListener() {
	         @SuppressWarnings("synthetic-access")
			public void actionPerformed(@SuppressWarnings("unused") final java.awt.event.ActionEvent evt) {
	        	 SearchPanel.this.searchButtonHandler();
	         }
		 });

		this.showContentLable = new JLabel();
		this.showContentLable.setText("chosen message content:");
		this.showContentLable.setPreferredSize(new java.awt.Dimension(149, 14));
		this.add(this.showContentLable, new AnchorConstraint(622, 312, 647, 109, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));


		this.resultsLable = new JLabel();
		this.resultsLable.setText("search results:");
		this.resultsLable.setFont(new Font("Californian FB",1,18));
		this.resultsLable.setPreferredSize(new java.awt.Dimension(114, 15));
		this.add(this.resultsLable, new AnchorConstraint(322, 264, 348, 109, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));


		//choose if the search is by text or dates:
		this.textOrDateButtonGroup = new ButtonGroup();

		this.byDateRadioButton = new JRadioButton();
		this.byDateRadioButton.setPreferredSize(new java.awt.Dimension(19, 18));
		this.textOrDateButtonGroup.add(this.byDateRadioButton);
		this.add(this.byDateRadioButton, new AnchorConstraint(231, 86, 264, 60, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));

		this.byDateRadioButton.addActionListener(new java.awt.event.ActionListener() {
	         @SuppressWarnings("synthetic-access")
			public void actionPerformed(@SuppressWarnings("unused") final java.awt.event.ActionEvent evt) {
	        	 SearchPanel.this.searchByDateHandler();
	         }
		 });

		this.textRadioButton = new JRadioButton();
		this.add(this.textRadioButton, new AnchorConstraint(119, 86, 148, 60, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
		this.textRadioButton.setPreferredSize(new java.awt.Dimension(19, 16));
		this.textOrDateButtonGroup.add(this.textRadioButton);

		this.textRadioButton.addActionListener(new java.awt.event.ActionListener() {
	         @SuppressWarnings("synthetic-access")
			public void actionPerformed(@SuppressWarnings("unused") final java.awt.event.ActionEvent evt) {
	        	 SearchPanel.this.searchByTextHandler();
	         }
		 });

		//if the search is by text - choose if the search is by author or content:
		this.searchByButtonGroup = new ButtonGroup();

		this.byAuthorRadioButton = new JRadioButton();
		this.add(this.byAuthorRadioButton, new AnchorConstraint(160, 735, 193, 573, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
		this.byAuthorRadioButton.setText("message author");
		this.byAuthorRadioButton.setPreferredSize(new java.awt.Dimension(119, 18));
		this.searchByButtonGroup.add(this.byAuthorRadioButton);

		this.byContentRadioButton = new JRadioButton();
		this.add(this.byContentRadioButton, new AnchorConstraint(162, 410, 193, 230, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
		this.byContentRadioButton.setText("message content");
		this.byContentRadioButton.setPreferredSize(new java.awt.Dimension(132, 17));
		this.searchByButtonGroup.add(this.byContentRadioButton);


		this.searchLabel = new JLabel();
		this.add(this.searchLabel, new AnchorConstraint(39, 557, 80, 448, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
		this.searchLabel.setText("Search");
		this.searchLabel.setFont(new Font("Californian FB",1,22));
		this.searchLabel.setPreferredSize(new java.awt.Dimension(80, 23));

		//the text to search by it:
		this.searchContent = new JTextField();
		this.add(this.searchContent, new AnchorConstraint(102, 901, 153, 116, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
		this.searchContent.setPreferredSize(new java.awt.Dimension(577, 28));

		//the text area to present the chosen message from the results list:
		this.postTextArea = new JTextArea();

		this.jScrollPane2 = new JScrollPane();
		this.jScrollPane2.setPreferredSize(new java.awt.Dimension(601, 150));
		this.jScrollPane2.setViewportView(this.postTextArea);
		this.add(this.jScrollPane2, new AnchorConstraint(657, 901, 930, 83, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));

		//the list that holds the search results:
		ListModel seacrhListModel = new SearchResListModel();
		this.reultsList = new JList();
		this.reultsList.setModel(seacrhListModel);
		this.reultsList.setCellRenderer(new SearchResListCellRenderer());
		this.reultsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		this.reultsList.addListSelectionListener(this);

		this.jScrollPane1 = new JScrollPane();
		this.jScrollPane1.setPreferredSize(new java.awt.Dimension(601, 130));
		this.jScrollPane1.setViewportView(this.reultsList);
		this.add(this.jScrollPane1, new AnchorConstraint(357, 901, 593, 83, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));


		//enables to choose the "to date" for the search:
		this.toDatePane = new JPanel();
		this.toDatePane.setPreferredSize(new java.awt.Dimension(97, 43));
		this.add(this.toDatePane, new AnchorConstraint(222, 615, 300, 483, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
		this.toDate = new JDateChooser(new Date());
		this.toDatePane.add(this.toDate);

		this.toDateLable = new JLabel();
		this.toDateLable.setText("to date:");
		this.toDateLable.setPreferredSize(new java.awt.Dimension(53, 14));
		this.add(this.toDateLable, new AnchorConstraint(239, 487, 264, 415, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));

		//enables to choose the "from date" for the search:
		this.fromDateLable = new JLabel();
		this.fromDateLable.setText("from date:");
		this.fromDateLable.setPreferredSize(new java.awt.Dimension(67, 13));
		this.add(this.fromDateLable, new AnchorConstraint(240, 200, 264, 109, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));

		this.fromDatePane = new JPanel();
		this.fromDatePane.setPreferredSize(new java.awt.Dimension(103, 42));
		this.add(this.fromDatePane, new AnchorConstraint(224, 335, 300, 195, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL, AnchorConstraint.ANCHOR_REL));
		this.fromDate = new JDateChooser(new Date());
		this.fromDatePane.add(this.fromDate);

		this.textRadioButton.doClick(); //simulates pressing this button, at initialization
	}

	private void presentResults(final Set<SearchResult> results)
	{
		Log.getLogger(Subsystem.PRESENTATION_MODEL).finest("presenting search resluts list in size "+results.size());
		((SearchResListModel)this.reultsList.getModel()).setSearchResults(results);
		this.reultsList.setSelectedIndex(0);
		if(results.isEmpty())
		{
			Log.getLogger(Subsystem.PRESENTATION_MODEL).fine("list is empty, no matches were found");
			JOptionPane.showMessageDialog(SearchPanel.this, "no matches were found") ;
		}
	}

	/**
	 * search by the given parameters, and present the results in the results list
	 * if no result - an empty list will be presented and a message to user will be produced.
	 */
	private void searchButtonHandler()
	{
		this.postTextArea.setText("");
		if(this.textRadioButton.isSelected())
		{

			if(this.searchContent.getText().equals("")){ //no input for the search
				JOptionPane.showMessageDialog(SearchPanel.this,
					"please enter something to search for", "error occured", JOptionPane.ERROR_MESSAGE) ;
			}

			else if(this.byAuthorRadioButton.isSelected())
			{
				try
				{
					Log.getLogger(Subsystem.PRESENTATION_MODEL).finest("searching by author - waits for server answer");
					Set<SearchResult> results = this.forum.searchByAuthor(this.searchContent.getText());
					this.presentResults(results);
				}
				catch (final RemoteException e)
				{
					Log.getLogger(Subsystem.PRESENTATION_MODEL).info("Remote problems thrown in search by author: "+e.getMessage()) ;
					JOptionPane.showMessageDialog(SearchPanel.this,
						"Communication problems, please try again", "error occured", JOptionPane.ERROR_MESSAGE) ;
				}
			}
			else if(this.byContentRadioButton.isSelected())
			{
				try
				{
					Log.getLogger(Subsystem.PRESENTATION_MODEL).finest("searching by content - waits for server answer");
					Set<SearchResult> results = this.forum.searchByContent(this.searchContent.getText());
					this.presentResults(results);
				}
				catch (final RemoteException e)
				{
					Log.getLogger(Subsystem.PRESENTATION_MODEL).info("Remote problems thrown in search by content: "+e.getMessage()) ;
					JOptionPane.showMessageDialog(SearchPanel.this,
						"Communication problems, please try again", "error occured", JOptionPane.ERROR_MESSAGE) ;
				}
			}
		}
		else if(this.byDateRadioButton.isSelected())
		{
			try
			{
				Log.getLogger(Subsystem.PRESENTATION_MODEL).finest("searching by dates - waits for server answer");
				Date from = DateTools.set(DateTools.set(DateTools.set(this.fromDate.getDate(), Calendar.SECOND, 0), Calendar.MINUTE, 0), Calendar.HOUR_OF_DAY, 0) ;
				Date to = DateTools.set(DateTools.set(DateTools.set(this.toDate.getDate(), Calendar.SECOND, 59), Calendar.MINUTE, 59), Calendar.HOUR_OF_DAY, 23) ;
				Set<SearchResult> results = this.forum.searchByDate(from, to);
				this.presentResults(results);
			}
			catch (final RemoteException e)
			{
				Log.getLogger(Subsystem.PRESENTATION_MODEL).info("Remote problems thrown in search by date: "+e.getMessage()) ;
				JOptionPane.showMessageDialog(SearchPanel.this,
					"Communication problems, please try again", "error occured", JOptionPane.ERROR_MESSAGE) ;
			}
		}
	}

	private void searchByDateHandler()
	{
		//disable the search by text:
		this.searchContent.setEditable(false);
		this.searchContent.setEnabled(false);
		this.byAuthorRadioButton.setEnabled(false);
		this.byContentRadioButton.setEnabled(false);

		//enable the search by date:
		this.fromDate.setEnabled(true);
		this.toDate.setEnabled(true);
	}

	private void searchByTextHandler()
	{
		//disable the search by date:
		this.fromDate.setEnabled(false);
		this.toDate.setEnabled(false);

		//enable the search by text:
		this.searchContent.setEditable(true);
		this.searchContent.setEnabled(true);
		this.byAuthorRadioButton.setEnabled(true);
		this.byContentRadioButton.setEnabled(true);
		this.byContentRadioButton.doClick(); //simulate pressing
	}





























}
